﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Common.Dao;
using Common.Model;
using Common.Redis;
using ikvm.extensions;
using log4net;
using Spider.Spider;
using Spider.Util;

namespace Spider.Service
{
    public class CrawlerService
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(CrawlerService));

        //保存和更新云财经新闻
        public static void CrawlingAndStoreYunFincalNews()
        {
            var from = "云财经";

            //获取相关tag的最新日期
            DateTime lastNewsDateTime = NewsRedisDbProvider.GetLastNewsDateTime(from);
            Log.Info(lastNewsDateTime);
            //抓取新闻
            var yunFincalSpider = new YunFincalSpider();
            var news = yunFincalSpider.GetNews(lastNewsDateTime, DateTime.Now);
            //保存新闻
            if (news != null && news.Count > 0)
            {
                var now = DateTime.Now;

                lastNewsDateTime = news.First().SiteTime;
                foreach (var item in news)
                {
                    item.CrawlingTime = now;
                    if (item.SiteTime > lastNewsDateTime)
                        lastNewsDateTime = item.SiteTime;
                }

                NewsDao.BatchSaveNews(news);

                //更新相关tag的最新日期到redis
                NewsRedisDbProvider.SetLastNewsDatetime(from, lastNewsDateTime);
            }
        }

        //保存和更新P5w问答
        public static void CrawlingAndStoreP5WQuestion()
        {
            var from = "P5w";

            //获取最新问题日期
            var lastestQuestion = QuestionAnswerDao.GetLastestQuestion();
            var lastNewsDateTime = DateTime.Parse("2018-02-20");
            if (null != lastestQuestion)
                lastNewsDateTime = lastestQuestion.QuestionTime;

            //抓取问题
            var spider = new P5WSpider();
            var question = spider.GetQuestion(lastNewsDateTime, false);
            //保存问题
            if (question != null && question.Count > 0)
            {
                lastNewsDateTime = question.Max(m => m.QuestionTime);
                QuestionAnswerDao.BatchSaveQuestion(question);

                //更新相关tag的最新日期到redis
                NewsRedisDbProvider.SetLastQuestionDatetime(lastNewsDateTime);
            }
        }

        //保存和更新P5w问答
        public static void CrawlingAndStoreP5WAnswer()
        {
            var from = "P5w";

            //获取最新问题日期
            var lastestAnswer = QuestionAnswerDao.GetLastestAnswer();
            var lastNewsDateTime = DateTime.Parse("2018-02-20");
            if (!string.IsNullOrEmpty(lastestAnswer?.Answer))
            {
                lastNewsDateTime = lastestAnswer.AnswerTime;
            }

            //抓取问题
            var spider = new P5WSpider();
            var answers = spider.GetQuestion(lastNewsDateTime, true);
            //保存问题
            if (answers != null && answers.Count > 0)
            {
                var now = DateTime.Now;

                lastNewsDateTime = answers.Max(m => m.QuestionTime);
                QuestionAnswerDao.BatchSaveAnswer(answers);

                //更新相关tag的最新日期到redis
                NewsRedisDbProvider.SetLastAnswerDatetime(lastNewsDateTime);
            }
        }

        //保存和更新短线王
        public static void CrawlingDxw()
        {
            var from = "dxw";
            var dictionary = DxwSpider.GetEvents(DateTime.Now.AddDays(-1));

            var dxwEvents = new List<DxwEvent>();
            foreach (var events in dictionary.Values.ToList())
                dxwEvents.AddRange(events);
            dxwEvents = dxwEvents.Distinct(new EventCompartor()).ToList();

            var dxwBlocksDic = DxwBlockDao.GetDxwBlock().Distinct(new BlockCompartor())
                .ToDictionary(block => block.BlockName, block => block.TopicName ?? "");

            var news = Util.Util.Dxwevents2News(dxwEvents);
            Util.Util.DxwBlockMapping(news, dxwBlocksDic);

            DxwEventDao.BatchSaveEvents(dxwEvents);
            NewsDao.BatchSaveNews(news);
        }

        public static void CrawlingStockName()
        {
            var stockName = StockNameSpider.GetStockName();
            StockNameDao.BatchSaveStocks(stockName);
        }

        public static void CrawlingCompanyNotice()
        {
            CompanyNotice companyNotice = CompanyNoticeDao.GetLastNotice();
            DateTime startTime = DateTime.Parse("2018-01-01");
            if (null != companyNotice)
            {
                startTime = companyNotice.SiteTime;
            }
            startTime = startTime.AddDays(-1);

            List<Announcements> announcementses = CompanyNoticeSpider.GetPubnote(startTime, true);
            var companyNotices = announcementses.Select(m => new CompanyNotice()
            {
                Id = m.announcementId,
                AdjunctUrl = m.adjunctUrl,
                CrawlingTime = DateTime.Now,
                SiteTime = m.time,
                StockCode = m.secCode,
                Title = m.announcementTitle,
                Content = m.announcementContent
            }).ToList();
            CompanyNoticeDao.BatchSaveNotices(companyNotices);
        }

        public static void CrawlingQa()
        {
            var lastestShQuestion = QuestionAnswerDao.GetLastestShQuestion();
            var lastestShAnswer = QuestionAnswerDao.GetLastestShAnswer();
            var lastestShQuestionTime = DateTime.Today;
            var lastestShAnswerTime = DateTime.Today;

            if (null != lastestShQuestion)
            {
                lastestShQuestionTime = lastestShQuestion.QuestionTime;
            }

            if (null != lastestShAnswer)
            {
                lastestShAnswerTime = lastestShAnswer.AnswerTime;
            }

            Log.Info("lastestShQuestionTime = " + lastestShQuestionTime);
            Log.Info("lastestShAnswerTime = " + lastestShAnswerTime);

            var shQuestion= ShQaSpider.GetQuestion(lastestShQuestionTime, DateTime.Now);
            var shAnswers = ShQaSpider.GetAnswers(lastestShAnswerTime, DateTime.Now);
            
       
            QuestionAnswerDao.BatchSaveQuestion(shQuestion);
            QuestionAnswerDao.BatchSaveAnswer(shAnswers);

            var lastestSzAnswer = QuestionAnswerDao.GetLastestSzAnswer();
            var lastestSzQuestion = QuestionAnswerDao.GetLastestSzQuestion();

            var lastestSzAnswerTime = DateTime.Today;
            var lastestSzQuestionTime = DateTime.Today;

            if (null != lastestSzQuestion)
            {
                lastestSzQuestionTime = lastestSzQuestion.QuestionTime;
            }

            if (null != lastestSzAnswer)
            {
                lastestSzAnswerTime = lastestSzAnswer.QuestionTime;
            }

            var szQuestion = SzQaSpider.GetQuestion(lastestSzQuestionTime, DateTime.Now);
            var szAnswers = SzQaSpider.GetAnswers(lastestSzAnswerTime, DateTime.Now);

            Log.Info("lastestSzQuestionTime = " + lastestSzQuestionTime);
            Log.Info("lastestSzAnswerTime = " + lastestSzAnswerTime);

            QuestionAnswerDao.BatchSaveQuestion(szQuestion);
            QuestionAnswerDao.BatchSaveAnswer(szAnswers);
        }

        /// <summary>
        /// 爬取龙虎榜
        /// </summary>
        public static void CrawlingHotList()
        {
            HotList hotList = RtnHotListDao.GetLast();
            List<HotList> hotLists = null;
            if (hotList == null)
            {
                hotLists = RtnHotListSpider.GetYHotList();
                if (null != hotLists && hotLists.Any())
                {
                    RtnHotListDao.BatchSaveNotices(hotLists);
                }

                return;
            }
            var dateTime = DateTime.ParseExact(hotList.Date, "yyyyMMdd", CultureInfo.CurrentCulture);
            if (dateTime >= DateTime.Today)
            {
                return;
            }
            hotLists = RtnHotListSpider.GetHotList(dateTime);
            if (null != hotLists && hotLists.Any())
            {
                RtnHotListDao.BatchSaveNotices(hotLists);
            }
        }

        /// <summary>
        /// 回补原因，收盘5点，以及当日晚上8点回补
        /// </summary>
        public static void CrawlingCloseReason()
        {
            var quoteRts = HqRedisProvider.GetHq();
            var zdgp =
                quoteRts.Where(
                        m =>
                            m.High >=
                            Math.Round(Math.Round(m.PreClose * (decimal) 1.10, 2, MidpointRounding.AwayFromZero), 2,
                                MidpointRounding.AwayFromZero))
                    .Where(m =>
                    {
                        var time = DateTime.Parse(m.Time);
                        return DateTime.Today < time;
                    })
                    .Select(m => m.StkCode)
                    .ToList();

            var blockingCollection = new List<RtnCloseReason>();

            foreach (var stkCode in zdgp)
            {
                List<RtnCloseReason> upedDetailStockbyId = RtnCloseSpider.UpedDetailStockbyId(stkCode);
                if (null == upedDetailStockbyId)
                {
                    continue;
                }
                foreach (var rtnCloseReason in upedDetailStockbyId)
                {
                    blockingCollection.Add(rtnCloseReason);
                }
                Thread.Sleep(1000);
            }

            foreach (var rtnCloseReason in blockingCollection)
            {
                rtnCloseReason.Title = rtnCloseReason.Title.replaceAll("<em class=\"hl\">", "");
                rtnCloseReason.Title = rtnCloseReason.Title.replaceAll("</em>", "");
            }
            RtnCloseReasonDao.SaveReason(blockingCollection.ToList());
        }


        public static void CrawlingDadayouziWechatFupan()
        {
            List<DadayouziFupan> crawlingDadayouziFupans = DadayouziWechatFupanSpider.CrawlingDadayouziFupans();
            if (null != crawlingDadayouziFupans)
            {
                DadayouziFupanDao.BatchSave(crawlingDadayouziFupans);
            }
        }
        
        /// <summary>
        /// 实时获取涨停原因
        /// </summary>
        public static void CrawlingCloseReasonRealTime()
        {
            var date = DateTime.Today.ToString("yyyy-MM-dd");
            var quoteRts = HqRedisProvider.GetHq();
            var zdgp =
                quoteRts.Where(
                        m =>
                            m.High >=
                            Math.Round(Math.Round(m.PreClose * (decimal) 1.10, 2, MidpointRounding.AwayFromZero), 2,
                                MidpointRounding.AwayFromZero))
                    .Where(m =>
                    {
                        var time = DateTime.Parse(m.Time);
                        return DateTime.Today < time;
                    })
                    .Select(m => m.StkCode)
                    .ToList();

            var blockingCollection = new List<RtnCloseReason>();

            foreach (var stkCode in zdgp)
            {
                List<RtnCloseReason> upedDetailStockbyId = RtnCloseSpider.UpedDetailRtbyjson(date, stkCode);
                if (null == upedDetailStockbyId)
                {
                    continue;
                }
                foreach (var rtnCloseReason in upedDetailStockbyId)
                {
                    blockingCollection.Add(rtnCloseReason);
                }
                Thread.Sleep(1000);
            }

            foreach (var rtnCloseReason in blockingCollection)
            {
                rtnCloseReason.Title = rtnCloseReason.Title.replaceAll("<em class=\"hl\">", "");
                rtnCloseReason.Title = rtnCloseReason.Title.replaceAll("</em>", "");
            }
            RtnCloseReasonDao.SaveReason(blockingCollection.ToList());
        }
    }
}